home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
madtrb17.arc
/
TDIR.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1985-10-06
|
17KB
|
532 lines
PROGRAM Volume;
TYPE
Str11 = String[11];
Str255 = String[255];
Reg = Record case Integer of
1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer);
2: (AL,AH,BL,BH,CL,CH,DL,DH : Byte);
End;
XFCB = Record { Extended File Control Block }
Flag : Byte; { Set to $FF to Identify as Extended FCB }
FRes : Array[1..5] of Byte; { 5 Reserved Bytes }
Att : Byte; { Attribute of File }
Drive : Byte; { 0 = Default, 1 = A, 2 = B }
FName : Array[1..8] of Char; { File Name }
Ext : Array[1..3] of Char; { Extension }
CBlock : Integer; { Current Block Number }
RSize : Integer; { Logical Record Size }
FSize : Integer; { File Size }
Date : Integer; { Date Created/Updated }
SRes : Array[1..10] of Byte; { 10 Reserved Bytes }
RNum : Byte; { Cur. Rel. Record Number in Block }
RRNum : Array[1..4] of Byte; { Rel. Rec. Rel. to Begining of File }
End;
DTARec = Record
XStuff : Array[1..7] of Byte; { 1st 7 bytes of Ext. FCB }
DDrive : Byte; { Drive Number }
FileName : Array[1..8] of Char; { File Name }
Extension : Array[1..3] of Char; { Extension }
Attribute : Byte; { Attribute }
Reserved : Array[1..10] of Byte; { 10 Reserved Bytes }
FileTime : Integer; { Time Created/Updated }
FileDate : Integer; { Date Created/Updated }
Cluster : Integer; { Starting Cluster Number }
FileSize : Array[1..4] of Byte; { File Size in Bytes }
End;
MFCB = Array[0..43] of char; { Modified XFCB Used to Rename Files }
E = Record
EName : String[8];
EExt : String[4];
End;
VAR
FCB : XFCB;
DTA : DTARec;
ModFCB : MFCB;
Regs : Reg;
OldVolumeName,
NewVolumeName : String[11];
OldVolumeNameDate : String[20];
Drive : Char;
Directory : String[80];
SpaceFree : Real;
AnyStr : String[255];
Day,Month,Year,
Hour,Minute,
ScreenCount : Integer;
Size : Real;
AP : Char;
ID : Boolean;
Entry : Array[1..80] of E;
EntryNum : Integer;
PROCEDURE Beep;
Begin
Sound(660);Delay(60);
Sound(440);Delay(60);
Sound(660);Delay(60);
Sound(440);Delay(60);
NoSound;
End; { procedure Beep }
PROCEDURE DrawBox(Top,Bottom,Left,Right : Integer);
VAR I:Integer;
Begin
LowVideo;
GotoXY(Left,Top); Write(#213);
For I := Left+1 to Right-1 do Write(#205);
Write(#184);
For I := Top+1 to Bottom-1 do begin
GotoXY(Left,I);Write(#179);
GotoXY(Right,I);Write(#179);
End;
GotoXY(Left,Bottom); Write(#212);
For I := Left+1 to Right-1 do Write(#205);
Write(#190);
NormVideo;
End; { procedure DrawBox }
PROCEDURE WriteHiLo(S:Str255);
VAR I : Integer;
Begin
For I := 1 to Length(S) do
If S[I] = '@' then LowVideo Else
If S[I] = '%' then NormVideo Else
Write(S[I]);
NormVideo;
End; { procedure WriteHiLow }
FUNCTION Freespace:real;
var
fr : real;
begin
with regs do
begin
dx := 0;
ah := $36;
MsDos(regs);
fr := bx;
if ax > 0 then Freespace := fr * ax * cx
else Freespace := 0
end;
end;
PROCEDURE TimeDate;
Begin
With DTA do begin
Size := (FileSize[1] * 1.0) +
(FileSize[2] * 256.0) +
(FileSize[3] * 65536.0);
Year := (FileDate shr 9) + 80;
Month := (FileDate shl 7) shr 12;
Day := (FileDate shl 11) shr 11;
Hour := FileTime shr 11;
If Hour >= 12 then begin
AP := 'p';
Hour := Hour - 12;
End Else AP := 'a';
If Hour = 0 then Hour := 12;
Minute := (FileTime shl 5) shr 10;
End;
End; { procedure TimeDate }
PROCEDURE ShowEntry;
VAR
I : Integer;
Str80 : String[80];
PROCEDURE ShowHeader;
Begin
ClrScr;
NormVideo;
Write('Volume Name: ',OldVolumeName);
LowVideo;
WriteLn(' ',SpaceFree:7:0,' Bytes Free');
NormVideo;
If Length(OldVolumeNameDate) > 0 then begin
WriteLn(' Created: ',OldVolumeNameDate);
ScreenCount := ScreenCount + 1;
End;
WriteLn(' Directory: ',Drive,':',Directory);
WriteLn;
LowVideo;
WriteLn('File Name Size Date Time');
WriteLn('--------------------------------------');
NormVideo;
ScreenCount := ScreenCount + 5;
End; { procedure ShowHeader }
Begin
With DTA do begin
TimeDate;
If (FCB.Att = 8) and (Attribute = 8) then Exit;
If ScreenCount >= 22 then begin
LowVideo;
ScreenCount := 0;
WriteLn('--------------------------------------');
WriteLn('MORE... press any key to continue');
Repeat until KeyPressed;
NormVideo;
End;
If ScreenCount = 0 then ShowHeader;
ScreenCount := ScreenCount + 1;
Attribute := Attribute and 31;
If Attribute <> 0 then LowVideo;
If Attribute = 8 then Write(FileName,Extension,' ')
Else If (Attribute and $10) = 16
then Write(FileName,Extension,' <DIR> ')
Else Write(FileName,' ',Extension,Size:8:0);
Write(' ',Month:2,'-');
If Day < 10 then Write('0');
Write(Day,'-',Year);
Write(' ',Hour:2,':');
If Minute < 10 then Write('0');
Write(Minute,ap);
If (Attribute and $01) = 1 then Write(' ReadOnly ');
If (Attribute and $02) = 2 then Write(' Hidden ');
If (Attribute and $04) = 4 then Write(' System ');
If (Attribute and $08) = 8 then Write(' <-- Volume Name!');
If (Attribute and $10) = 16 then Write(' SubDirectory');
If (Attribute and $20) = 32 then Write(' Archive');
NormVideo;
WriteLn;
End; { with DTA }
End; { procedure ShowEntry }
PROCEDURE SetDTA;
Begin
Regs.AX := $1A00; { Func.Call $1A (Set DTA) }
Regs.DS := Seg(DTA);
Regs.DX := Ofs(DTA);
MsDos(Regs);
End;
PROCEDURE FindFirstEntry(SearchAttribute : Byte);
VAR I : Integer;
Begin
With FCB do begin
FillChar(FCB,SizeOf(FCB),0);
Flag := $FF;
Att := SearchAttribute;
For I := 1 to 8 do FName[I] := '?';
For I := 1 to 3 do Ext[I] := '?';
Regs.DS := Seg(FCB);
Regs.DX := Ofs(FCB);
Regs.AX := $1100; { Func.Call $11 (Search for First Entry) }
MsDos(Regs);
If (Att = 8) and (DTA.Attribute = 8) and (Regs.AL <> $FF) then begin
TimeDate;
OldVolumeName := DTA.FileName + DTA.Extension;
Str(Month,AnyStr);
OldVolumeNameDate := AnyStr + '-';
If Day < 10 then OldVolumeNameDate := OldVolumeNameDate + '0';
Str(Day,AnyStr);
OldVolumeNameDate := OldVolumeNameDate + AnyStr + '-';
Str(Year,AnyStr);
OldVolumeNameDate := OldVolumeNameDate + AnyStr + ' ';
Str(Hour:2,AnyStr);
OldVolumeNameDate := OldVolumeNameDate + AnyStr + ':';
If Minute < 10 then OldVolumeNameDate := OldVolumeNameDate + '0';
Str(Minute,AnyStr);
OldVolumeNameDate := OldVolumeNameDate + AnyStr + AP;
End;
End; { with FCB }
End; { procedure FindFirstEntry }
PROCEDURE FindNextEntry;
Begin
Regs.DS := Seg(FCB);
Regs.DX := Ofs(FCB);
Regs.AX := $1200; { Func.Call $12 (Search for Next Entry) }
MsDos(Regs);
End; { procedure FindNextEntry }
PROCEDURE FixName(VAR S:Str11);
VAR I : Integer;
Begin
For I := 1 to Length(S) do S[I] := UpCase(S[I]);
S := S + Copy(' ',1,11-Length(S));
End; { procedure FixName }
PROCEDURE ChangeVolumeName(Old,New:Str11);
VAR I : Integer;
Begin
FixName(Old);
FixName(New);
FillChar(ModFCB,SizeOf(ModFCB),#32);
ModFCB[0] := #255;
ModFCB[6] := #8;
ModFCB[7] := #0;
For I := 1 to 11 do ModFCB[I+7] := Old[I];
For I := 1 to 11 do ModFCB[I+23] := New[I];
Regs.DS := Seg(ModFCB);
Regs.DX := Ofs(ModFCB);
Regs.AX := $1700;
MsDos(Regs);
End; { procedure ChangeVolumeName }
PROCEDURE CreateVolumeName(S:Str11);
VAR I : Integer;
Begin
With FCB do begin
FillChar(FCB,SizeOf(FCB),0);
Flag := $FF;
Att := $08;
Drive := $00;
FixName(S);
For I := 1 to 8 do FName[I] := S[I];
For I := 9 to Length(S) do Ext[I-8] := S[I];
Regs.DS := Seg(FCB);
Regs.DX := Ofs(FCB);
Regs.AX := $1600; { Func.Call $16 (Create File) }
MsDos(Regs);
WriteLn(Regs.AL,' Opening File');
Regs.DS := Seg(FCB);
Regs.DX := Ofs(FCB);
Regs.AX := $1000; { Func.Call $10 (Close File) }
MsDos(Regs);
WriteLn(Regs.AL,' Closing File');
End; { with FCB }
End; { procedure CreateVolumeName }
PROCEDURE FindVolume;
VAR I : Integer;
Begin
With FCB do begin
FindFirstEntry(55);
If Regs.AL <> $FF then ShowEntry;
If Regs.AL <> $FF then begin
Repeat
FindNextEntry;
If Regs.AL <> $FF then ShowEntry;
Until Regs.AL = $FF;
End;
LowVideo;
WriteLn('--------------------------------------');
Write('Press any key to continue... ');
Repeat until KeyPressed;
NormVideo;
End; { with FCB }
End; { procedure FindVolume }
PROCEDURE DisplayID;
Begin
DrawBox(1,25,55,79);
GotoXY(57,2);Write('written by');
GotoXY(57,3);Write('---------------------');
GotoXY(57,4);Write('JAMESTOWN SOFTWARE');
GotoXY(57,5);Write('2508 Valley Forge Dr.');
GotoXY(57,6);Write('Madison, WI 53719');
GotoXY(57,7);Write('---------------------');
GotoXY(57,8);Write('on a modified');
GotoXY(57,9);Write('SHAREWARE BASIS');
GotoXY(57,11);Write('If you like and');
GotoXY(57,12);Write('use this program,');
GotoXY(57,13);Write('send me a letter and');
GotoXY(57,14);Write('let me know...');
GotoXY(57,16);Write('If you would like a');
GotoXY(57,17);Write('copy of the TURBO');
GotoXY(57,18);Write('Pascal source code,');
GotoXY(57,19);Write('send at least a');
GotoXY(57,20);Write('couple of quarters!');
GotoXY(57,21);Write('---------------------');
GotoXY(57,22);Write('(Who said you can','''','t');
GotoXY(57,23);Write(' get rich writing');
GotoXY(57,24);Write(' software?!?)');
End; { procedure DisplayID }
PROCEDURE SelectEntry(VAR Choice:Integer);
VAR Ch:Char;
X,Y,OldChoice : Integer;
Begin
OldChoice:=Choice;
Repeat
X:=1+(((OldChoice-1) mod 4)*14);
Y:=7+((OldChoice-1) div 4);
GotoXY(X,Y);
Write(Entry[OldChoice].EName,Entry[OldChoice].EExt);
Textcolor(Black);
TextBackground(LightGray);
X:=1+(((Choice-1) mod 4)*14);
Y:=7+((Choice-1) div 4);
GotoXY(X,Y);
Write(Entry[Choice].EName,Entry[Choice].EExt);
GotoXY(1,8+(EntryNum div 5));
NormVideo;
OldChoice:=Choice;
Repeat
Read(Kbd,Ch);
If Ch = #27 then begin
Read(Kbd,Ch);
If NOT (Ch in [#71,#72,#75,#77,#79,#80]) then Beep;
End;
Until Ch in [#27,#71,#72,#75,#77,#79,#80,#13];
If Ch=#71 then Choice:=1;
If Ch=#72 then Choice:=Choice-4;
If Ch=#77 then Choice:=Choice+1;
If Ch=#75 then Choice:=Choice-1;
If Ch=#79 then Choice:=EntryNum;
If Ch=#80 then Choice:=Choice+4;
If Choice > EntryNum then Choice:=1;
If Choice < 1 then Choice:=EntryNum;
Until Ch in [#13,#27];
If Ch=#27 then Choice := 999;
End; { procedure SelectEntry }
PROCEDURE Menu;
VAR
MenuChoice,Ch : Char;
I : Integer;
S,S1 : Str255;
Begin
Repeat
ClrScr;
If ID then DisplayID;
GotoXY(1,1);
GetDir(0,Directory);
SetDTA;
FindFirstEntry(8);
If Regs.AL = $FF then begin
OldVolumeName := '<NONE>';
OldVolumeNameDate := '';
End;
For I := 1 to Length(Directory) do Directory[I] := UpCase(Directory[I]);
Drive := Directory[1];
Directory := Copy(Directory,3,length(Directory));
S:='@ Drive: %'+Drive;
WriteHiLo(S); WriteLn;
S:='@Directory: %'+Directory;
WriteHiLo(S); WriteLn;
S:='@ Volume: %'+OldVolumeName;
WriteHiLo(S); WriteLn;
Write('------------------------------------------------');
GotoXY(1,5);
LowVideo;
WriteLn('SUBDIRECTORIES on Selected Drive/Directory: ');
WriteLn;
NormVideo;
EntryNum := 0;
I:=0;
With FCB do begin
FindFirstEntry(16);
If (Regs.AL <> $FF) and ((DTA.Attribute and $10) = 16) then begin
I:=1;
Write(DTA.FileName,DTA.Extension);
LowVideo;
Write(' | ');
NormVideo;
EntryNum := EntryNum + 1;
Entry[EntryNum].EName := DTA.FileName;
Entry[EntryNum].EExt := DTA.Extension;
End;
If Regs.AL <> $FF then begin
Repeat
FindNextEntry;
If (Regs.AL <> $FF) and ((DTA.Attribute and $10) = 16) then begin
Write(DTA.FileName,DTA.Extension);
LowVideo;
Write(' | ');
NormVideo;
EntryNum := EntryNum + 1;
Entry[EntryNum].EName := DTA.FileName;
Entry[EntryNum].EExt := DTA.Extension;
I:=I+1;
If I >= 4 then begin
WriteLn;
I := 0
End;
End;
Until Regs.AL = $FF;
End;
End; { with FCB }
GotoXY(1,17);
WriteHiLo('@Select %A@ctive Drive');
WriteHiLo(' -- @Select %D@irectory'); WriteLn;
WriteHiLo('@Change or Create %V@olume Name (A: or B: only)'); WriteLn; WriteLn;
WriteHiLo('%S@how Disk Directory ');
If ID = False then WriteHiLo('@Show Author %I@dentification');
WriteLn; WriteLn;
WriteHiLo('%Q@uit and return to DOS in selected subdirectory'); WriteLn; WriteLn;
Write('>');
Repeat
Read(Kbd,MenuChoice);
MenuChoice := Upcase(MenuChoice);
If NOT (MenuChoice in ['D','A','V','S','Q','I']) then Beep;
Until MenuChoice in ['D','A','V','S','Q','I'];
Write(MenuChoice);
If ID = True then begin
ID := False;
Window(55,1,79,25);ClrScr;
Window(1,1,80,25)
End;
Case MenuChoice of
'A' : Begin
S := '';
GotoXY(12,1); ClrEol;
ReadLn(S);
S := S[1] + ':';
{$I-}
ChDir(S);
{$I+}
If IOResult <> 0 then Beep;
End;
'D' : If EntryNum > 0 then begin
Window(1,16,79,25);ClrScr;
Window(1,1,80,25);
GotoXY(1,23);
WriteLn('Select with cursor keys, then press return. (Press Esc to abort)');
WriteHiLo('@Double dot (..) moves up one subdirectory...');
I:=1;
SelectEntry(I);
If I<>999 then begin
S1:=Entry[I].EName;
S:='';
For I:=1 to Length(S1) do If S1[I]<>' ' then S:=S+S1[I];
{$I-}
ChDir(S);
{$I+}
If IOResult <> 0 then Beep;
End;
End;
'V' : Begin
If Drive in ['A'..'B'] then begin
NewVolumeName := ' ';
GotoXY(12,3); ClrEol;
Read(NewVolumeName);
FixName(NewVolumeName);
GotoXY(1,6);
If OldVolumeName = '<NONE>'
then Write('Create NEW Volume Name: ',NewVolumeName)
Else Write('Change ',OldVolumeName,' to ',NewVolumeName,'?');
Write(' Y/N ');
Repeat
Read(Kbd,Ch);
Ch := UpCase(Ch);
If NOT (Ch in ['Y','N']) then Beep;
Until Ch in ['Y','N'];
If Ch = 'Y' then
If OldVolumeName = '<NONE>'
then CreateVolumeName(NewVolumeName)
Else ChangeVolumeName(OldVolumeName,NewVolumeName);
End;
End;
'S' : Begin
SpaceFree := FreeSpace;
ClrScr;
ScreenCount := 0;
FindVolume;
End;
'I' : ID := True;
End;
Until MenuChoice = 'Q';
End; { procedure Menu }
Begin
ID := True;
Menu;
ClrScr;
End.I